#ifndef TBLOCK_H
#define TBLOCK_H

#include "crossbit/common.h"
#include "crossbit/Exit.h"
#include <vector>

namespace crossbit {

		class TCache;

		class TBlock {
				public:
						friend class TCache;

						TBlock()
						{
								tb_exits.reserve(GLOBAL::MAX_BLOCK_CHAIN_NUM * 3);
								run_count = 0;
								is_super_block = false;
						}

						virtual ~TBlock() 
						{ 
						}

						void genMallocWrap()
						{
						}

						// --------------------------------------------
						//		Basic Management
						// --------------------------------------------

						// Return size of the target code block
						XTUint32 getSize() const
						{ 
								return tb_size; 
						}

						// Return the entry address of the target code
						XTMemAddr enterAddr() const
						{ 
								return tb_tcode; 
						}

						// Return size of the target code block
						XTUint32 setSize(XTUint32 size)
						{ 
								tb_size = size; 
						}

						// -------------------------------------------------
						//		    Exit management
						// -------------------------------------------------

						//static const std::string EXITREASON2STR[4];

						// Return TBlock::Exit reference
						Exit &getExit(XTUint32 i)
						{
								if( i >= 0 && i < tb_exits.size() )
										return tb_exits[i];
								else
								{
									    		
										return tb_exits[-1];
								}
						}

						XTInt32 addExit( Exit e )
						{
								tb_exits.push_back(e);
								if( tb_exits.size() > GLOBAL::MAX_BLOCK_CHAIN_NUM * 2  ) 
									printf("ERROR==============\n"); 
								return tb_exits.size() - 1;
						}

						XTUint32 exitNums()
						{
								return tb_exits.size();	
						}

						// ----------------------------------------------
						//		relocation management
						// ----------------------------------------------

						void addRelocationPoint(XTUint32 where)
						{
								tb_relocations.push_back(where);
						}

						void relocate(XTUint32 offset);

						void setSPC( XTMemAddr spc )
						{
								tb_spc = spc;
						}

						XTMemAddr getSPC()
						{
								return tb_spc;
						}

						//Add by suntingtao for build superblock		
						bool isSupperBlock( void ){ return is_super_block; }
						void setSuperBlock( void ) { is_super_block = true; }
						XTUint32 getRunCount( void ) { return run_count; }
						void  setRunCount( XTUint32 value ) { run_count = value;}
						XTMemAddr getRunCountAddr( void ) { return (XTMemAddr)&run_count;}

				protected:

						// duplicate TBlock is not allowed
						TBlock(const TBlock &tblock) {}
						TBlock& operator=(const TBlock &tblock) { return *this; }

						std::vector<Exit> tb_exits;
						XTMemAddr tb_spc;
						XTMemAddr	tb_tcode;
						XTUint32	tb_size;

						std::vector<int> tb_relocations;
						
						//Added by suntingtao, to collect the run time of the of this block.
						XTUint32  run_count;
						bool 	  is_super_block;
		};

}
#endif
